package functionchange;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

import javassist.ByteArrayClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

public class FunctionChange implements ClassFileTransformer {

//	private static String importstr = "\nimport main.StatisticsMap;\n";

	private static String prefix = "StatisticsStart = System.nanoTime();";

	private static String postfix = "StatisticsUse = System.nanoTime();";

	final static char point_regex = ';';
	
	private ICheckChange check;
	
	public FunctionChange(ICheckChange check)
	{
		this.check = check;
	}


	public byte[] transform(ClassLoader loader, String className,
			Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
			byte[] classfileBuffer) throws IllegalClassFormatException {
		System.out.println("transform  "+className);
		if (check==null||!check.classIsChange(className))
			return classfileBuffer;
		// 将‘/’替换为‘.’m比如monitor/agent/Mytest替换为monitor.agent.Mytest
		className = className.replace("/", ".");
		// 用于取得字节码类，必须在当前的classpath中，使用全称 ,这部分是关于javassist的知识
		try {
			ClassPool cp = ClassPool.getDefault();
			cp.insertClassPath(new ByteArrayClassPath(className, classfileBuffer));
			CtClass ctclass = cp.get(className);
			ctclass.defrost();
			// 循环一下，看看哪些方法需要加时间监测
			for (CtMethod method : ctclass.getDeclaredMethods()) {
				System.out.println("change "+className+" method "+method.getName());
				method.addLocalVariable("StatisticsStart", CtClass.longType);
				method.addLocalVariable("StatisticsUse", CtClass.longType);
				method.insertBefore(prefix);
				method.insertAfter(postfix);
				method.insertAfter("\nSystem.out.println(\"this method "+method.getName()+" cost:\" +(StatisticsUse - StatisticsStart)/1000.0/1000.0 +\"ms.\");");
			}
			ctclass.detach();
			return ctclass.toBytecode();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
